#ifndef NE_STL_INCLUDENE_STL_TYPE_TRAITS_H
#define NE_STL_INCLUDENE_STL_TYPE_TRAITS_H

#include "ne_stl_build.h"

namespace nstd {

template <typename T, T _value>
struct _integral_constant {
    static const T value = _value;
    operator T() const { return (value); }
    T operator()() const { return (value); }
};
template <typename T, T _value>
using integral_constant = _integral_constant<T, _value>;
template <bool _value>
using bool_constant = integral_constant<bool, _value>;
using true_type = bool_constant<true>;
using false_type = bool_constant<false>;
template <typename T>
struct is_bool : false_type {};
template <>
struct is_bool<bool> : true_type {};

template <bool _conditional, typename T = void>
struct enable_if {};
template <typename T>
struct enable_if<true, T> {
    using type = T;
};

template <bool _conditional, typename T1, typename T2>
struct conditional {
    using type = T1;
};
template <typename T1, typename T2>
struct conditional<false, T1, T2> {
    using type = T2;
};
template <typename T>
struct remove_const {
    using type = T;
};

template <typename T>
struct remove_const<const T> {
    using type = T;
};
template <typename T>
struct remove_reference {
    using type = T;
};

template <typename T>
struct remove_reference<T&> {
    using type = T;
};

template <typename T>
struct remove_reference<T&&> {
    using type = T;
};
template <typename T>
struct remove_cr {
    using type = typename remove_const<typename remove_reference<T>::type>::type;
};
template <typename T>
using is_standard_layout = std::is_standard_layout<T>;
namespace {
namespace detail {
template <typename... TArgs>
struct _Is_all_standard_layout {};
template <>
struct _Is_all_standard_layout<> : nstd::true_type {};
template <typename T, typename... TArgs>
struct _Is_all_standard_layout<T, TArgs...> : nstd::conditional<nstd::is_standard_layout<typename nstd::remove_cr<T>::type>::value,
                                                  _Is_all_standard_layout<TArgs...>,
                                                  nstd::false_type>::type {};
}  // namespace detail
namespace traits {
template <typename... T>
using _is_all_standard_layout = detail::_Is_all_standard_layout<T...>;
}  // namespace traits
}  // namespace
template <typename... T>
using is_all_standard_layout = traits::_is_all_standard_layout<T...>;

}  // namespace nstd

#endif  // !NE_STL_INCLUDENE_STL_TYPE_TRAITS_H
